/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package snmpagent;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
/**
 *
 *
 * @author jquinterob
 */
public class SNMPAgent {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws SocketException, IOException, ClassNotFoundException {
        int PUERTO=5161;
        byte msg[]=new byte[42];
        //Creamos el socket UDP del servidor en el pueto asociado
        DatagramSocket dgs = new DatagramSocket(PUERTO);
        /**
         * paquete en el que se env�a informaci�n al cliente
         */
        DatagramPacket dgpEnvio;
        /**
         * paquete en el que se recibe el arreglo de bytes que proviene del cliente
         */
        DatagramPacket dgpRecibido;
        Dao dao= new Dao();
        SNMPTrama objTrama;
        while (true){
            objTrama = new SNMPTrama();
            dgpRecibido = new DatagramPacket(new byte [42],42);
            //llega un datagrama
            dgs.receive(dgpRecibido);
            byte[] res = dgpRecibido.getData();
            dao.actualizarDatos();
            leerTramaSNMP(res, objTrama);
            System.out.println("Trama de entrada");
            System.out.println(new String(res));
            resolverConsulta(objTrama);
            msg = crearTramaSNMP(objTrama);
            dgpEnvio = new DatagramPacket(new byte [42],42);
            System.out.println("Trama de salida");
            System.out.println(new String(msg));
            responder(msg, dgpRecibido, dgpEnvio, dgs);
       }
    }

    public static void responder(byte[] respuesta,DatagramPacket dgpRecibido, DatagramPacket dgpEnvio, DatagramSocket dgs) throws IOException{
        dgpEnvio=new DatagramPacket(respuesta,respuesta.length,dgpRecibido.getAddress(),dgpRecibido.getPort());
        dgs.send(dgpEnvio);
    }

    private static void leerTramaSNMP(byte[] trama,SNMPTrama objTrama) {
        byte section[]=new byte[1];
        int j=0;
        int k=0;
        for(int i = 0;i<trama.length;i++){
               char tmp =(char)(trama[i]);
               if(tmp != '&'){
                    section[k]=trama[i];
                    if(k<section.length-1)
                        k++;
               }else{
                   j++;
                   if(j==1){
                       char tmp2 =(char)(section[k]);
                       objTrama.setVersion(tmp2);
                       section = new byte[7];
                   }
                   if(j==2){
                       objTrama.setComunidad((new String(section).trim()));
                       section = new byte[1];
                   }
                   if(j==3){
                       objTrama.setOperacion((int)section[k]);
                       section = new byte[8];
                   }
                   if(j==4){
                       objTrama.setId(toInt(section));
                       section = new byte[20];
                   }
                   if(j==5){
                       objTrama.setDato(new String(section));
                   }
                   k=0;
               }
        }
    }

    private static void resolverConsulta(SNMPTrama objTrama) {
        Dao dao= new Dao();
        if(objTrama.getVersion() == '0'){
            if(objTrama.getComunidad().equalsIgnoreCase("PUBLIC")){
                if(objTrama.getOperacion() == 16){
                    objTrama.setDato(dao.consultarMIB(Integer.toString(objTrama.getId())));
                }
                else{
                    objTrama.setDato("OPERACIONNOVALIDA");
                }
            }
            else if(objTrama.getComunidad().equalsIgnoreCase("PRIVATE")){
                if(objTrama.getOperacion() == 32){
                    if(dao.actualizarMIB()){
                        objTrama.setDato("OK");
                    }else{
                        objTrama.setDato("FAIL");
                    }
                }
                else{
                    objTrama.setDato("OPERACIONNOVALIDA");
                }
            }else{
                objTrama.setDato("COMUNIDADNOVALIDA");
            }
        }
        else{
            objTrama.setDato("VERSIONNOVALIDA");
        }
    }

    private static byte[] crearTramaSNMP(SNMPTrama objTrama) {
        byte res[]=new byte[42];
        int largoComunidad = objTrama.getComunidad().length();
        int largoDato = objTrama.getDato().length();
            res[0]= (byte) objTrama.getVersion();
            res[1]='&';
            for(int i=0;i<largoComunidad;i++){
                res[2+i] = (byte) objTrama.getComunidad().charAt(i);
            }
            res[largoComunidad+2]='&';
            res[largoComunidad+3]= (byte) objTrama.getOperacion();
            res[largoComunidad+4]='&';
            res[largoComunidad+5]=(byte) Character.getNumericValue(Integer.toString(objTrama.getId()).charAt(0));
            res[largoComunidad+6]=(byte) Character.getNumericValue(Integer.toString(objTrama.getId()).charAt(1));
            res[largoComunidad+7]=(byte) Character.getNumericValue(Integer.toString(objTrama.getId()).charAt(2));
            res[largoComunidad+8]=(byte) Character.getNumericValue(Integer.toString(objTrama.getId()).charAt(3));
            res[largoComunidad+9]=(byte) Character.getNumericValue(Integer.toString(objTrama.getId()).charAt(4));
            res[largoComunidad+10]=(byte) Character.getNumericValue(Integer.toString(objTrama.getId()).charAt(5));
            res[largoComunidad+11]=(byte) Character.getNumericValue(Integer.toString(objTrama.getId()).charAt(6));
            res[largoComunidad+12]=(byte) Character.getNumericValue(Integer.toString(objTrama.getId()).charAt(7));
            res[largoComunidad+13]='&';
            for(int i=0;i<20;i++){
                if(i<largoDato){
                    res[largoComunidad+14+i] = (byte) objTrama.getDato().charAt(i);
                }
                else{
                    res[largoComunidad+14+i] = (byte)' ';
                }
            }
            res[largoComunidad+34]='&';
            return res;
    }
    public static int toInt( byte[] bytes ) {
        int result = 0;
        int multi= 10000000;
        for (int i=0; i<bytes.length; i++) {
          result = result + ((int)(bytes[i])*multi);
          multi = multi/10;
        }
        return result;
     }


}
